home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1991 …esperately Seeking Seven / Desperately Seeking Seven.2mg / Dev.CD.8 / Essentials / Tools / DTS.Samples / SC16Aware / Config.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-25  |  8.5 KB  |  238 lines  |  [04] ASCII Text (0x0000)

  1. /*
  2.     Config.c -- Version 3.0 
  3.     
  4.     Developer Technical Support Apple II Sample Code
  5.  
  6.     Copyright (c) 1990 by Apple Computer, Inc.
  7.     All Rights Reserved.
  8.  
  9.     This file contains the routines for loading and saving
  10.     configuration data for the sample network aware application.
  11. */
  12.  
  13. #include <types.h>              /* {CIIGSIncludes}types.h */
  14. #include <GSOS.h>               /* {CIIGSIncludes}GSOS.h */
  15. #include <MiscTool.h>           /* {CIIGSIncludes}MiscTool.h */
  16. #include <Window.h>             /* {CIIGSIncludes}Window.h */
  17. #include "Aware.h"
  18.  
  19. /*
  20.     The string asciiTime holds the configuration data (the time
  21.     that the configuration was last saved, or the program was
  22.     exited).  It is stored as a C-string (zero byte terminated)
  23.     of 20 characters.
  24. */
  25. char asciiTime[21];
  26.  
  27.  
  28. /*
  29.     This routine, c2gstr, takes a C-string and creates a GSOS
  30.     class 1 string (i.e. a string with a leading length WORD).
  31.     The GSOS string is a copy, and the C-string is left
  32.     unchanged.
  33. */
  34. void c2gstr(cstr,gstr)
  35. char *cstr;
  36. GSString32 *gstr;
  37. {
  38.     char *src,*dest;
  39.     
  40.     src = cstr;
  41.     dest = gstr->text;
  42.     
  43.     while (*src) {
  44.         *(dest++) = *(src++);
  45.     }
  46.     
  47.     gstr->length = src-cstr;
  48. }
  49.  
  50.  
  51. /*
  52.     loadConfig()
  53.     
  54.     This routine does the actual work of loading the configuration
  55.     information from the user's configuration file into the global
  56.     variable asciiTime.  It supplies a default value of "<unknown>"
  57.     if the configuration data cannot be read (for example, if none
  58.     has been saved).
  59.     
  60.     Note the use of the "@" prefix in the pathname of the config-
  61.     uration file.  This allows each user name to have its own
  62.     file when run from a network, or for the file to be saved
  63.     with the application when run from a local disk.  You don't
  64.     have to have special code to access the network; the "@"
  65.     prefix is set up automatically just before your application
  66.     is launched.
  67.     
  68.     Also note the use of the requestAccess field of the class 1
  69.     Open call (OpenGS).  Since we only need to read from the file,
  70.     that's the only access we will request.  This lets several
  71.     users (even users logged on with the same name) to load in
  72.     the file at the same time.  This is particularly important in
  73.     classroom settings where an entire class may launch the same
  74.     application at the same time, all trying to open the same file
  75.     at the same time.
  76. */
  77. void loadConfig()
  78. {
  79.     Word cRefNum;
  80.     GSString32 path;
  81.     OpenRecGS myOpenRec;
  82.     RefNumRecGS myCloseRec;
  83.     IORecGS myReadRec;
  84.  
  85.     
  86.     /*  First, put the pathname into a suitable form for the OpenGS
  87.         call.  Convert it from a C-string to a GSString. */
  88.     c2gstr("@:Aware.Config",&path);
  89.     
  90.  
  91.     /*  Next, provide a suitable default value in case there is no
  92.         configuration file, or if there is an error while trying
  93.         to load it.  The default will be overwritten if the
  94.         configuration can be read from the file. */
  95.     strcpy(asciiTime,"<unknown>");
  96.  
  97.  
  98.     /*  Fill out the OpenGS parameter list and make the call to
  99.         open the file. */
  100.     myOpenRec.pCount = 3;                   /* include requestAccess! */
  101.     myOpenRec.pathname = &path;
  102.     myOpenRec.requestAccess = readEnable;   /* request read only */
  103.     OpenGS(&myOpenRec);                     /* do the Open call */
  104.  
  105.  
  106.     /* If the open succeeded, read in the data from the file. */    
  107.     if (!_toolErr) {
  108.     
  109.         myReadRec.pCount = 4;
  110.         myReadRec.refNum = myOpenRec.refNum;
  111.         myReadRec.dataBuffer = asciiTime;
  112.         myReadRec.requestCount = 20;        /* data is always 20 bytes long */
  113.         ReadGS(&myReadRec);
  114.         /* If the read succeeded, the default was overwritten by the
  115.             contents of the file.  Now, just put a zero byte at the
  116.             end of the string so that it can be used as a C-string. */
  117.         if (!_toolErr) {
  118.             asciiTime[myReadRec.transferCount] = 0;
  119.         }
  120.  
  121.         /* Close the configuration file. */
  122.         myCloseRec.pCount = 1;
  123.         myCloseRec.refNum = myOpenRec.refNum;
  124.         CloseGS(&myCloseRec);
  125.     }
  126. }
  127.  
  128.  
  129. /*
  130.     saveConfig()
  131.     
  132.     This routine does the actual work of saving the configuration
  133.     information to the user's configuration file from the global
  134.     variable asciiTime.
  135.     
  136.     Note the use of the "@" prefix in the pathname of the config-
  137.     uration file.  This allows each user name to have its own
  138.     file when run from a network, or for the file to be saved
  139.     with the application when run from a local disk.  You don't
  140.     have to have special code to access the network; the "@"
  141.     prefix is set up automatically just before your application
  142.     is launched.
  143.     
  144.     Also note the use of the requestAccess field of the class 1
  145.     Open call (OpenGS).  Even though we're only going to write
  146.     to the file, we open it for read/write.  There are two
  147.     reasons for this.  First, asking for write permission
  148.     prevents anybody else from getting either read or write
  149.     access, so asking for both read/write doesn't change the
  150.     access anybody else can get.  Second, since we're writing
  151.     a small amount (i.e. less than 512 bytes) at a time, the FST
  152.     will try to buffer the contents of the file and needs read
  153.     access to do this.  If it doesn't have read access, and you
  154.     write some bytes, set the mark ahead some bytes, and write
  155.     some more bytes, the bytes you skipped over cannot be
  156.     buffered, and their original contents will be lost.  In our
  157.     case, this isn't a problem since we write continuously from
  158.     the beginning of the file.
  159. */
  160. void saveConfig()
  161. {
  162.     Word cRefNum;
  163.     GSString32 path;
  164.     CreateRecGS myCreateRec;
  165.     OpenRecGS myOpenRec;
  166.     RefNumRecGS myCloseRec;
  167.     IORecGS myWriteRec;
  168.     int i;
  169.  
  170.  
  171.     /*  Update the configuration data by getting the current
  172.         date/time from the real time clock.  ReadAsciiTime
  173.         returns 20 characters with the high bit set, so I'll
  174.         clear the high bits and add a trailing zero byte to
  175.         make it a C-string. */
  176.     ReadAsciiTime(asciiTime);               /* get the current date/time */
  177.     for (i=0; i<20; i++)
  178.         asciiTime[i] = asciiTime[i] & 0x7F; /* clear high bit of char */
  179.     asciiTime[20] = '\0';                   /* make it a C string */
  180.  
  181.  
  182.     /*  Put the pathname into a suitable form for the OpenGS
  183.         call.  Convert it from a C-string to a GSString. */
  184.     c2gstr("@:Aware.Config",&path);         /* convert path to GSString */
  185.  
  186.  
  187.     /*  Create the file in case it doesn't exist yet.  If
  188.         it does exist, this call will return an error, and
  189.         we'll ignore it. */
  190.     myCreateRec.pCount = 4;
  191.     myCreateRec.pathname = &path;
  192.     myCreateRec.access = 0xC3;              /* full access, not invisible */
  193.     myCreateRec.fileType = 4;               /* storing it as a text file */
  194.     myCreateRec.auxType = (LongWord) 0;     /* record length = 0, plain ASCII */
  195.     CreateGS(&myCreateRec);                 /* create the file */
  196.  
  197.     
  198.     /*  Note: I'm not asking for any of the file information (such
  199.         as file type, auxtype, size, etc.) to be returned.  If I did
  200.         ask for it, and I had make changes but not see files access,
  201.         the Open would fail (since I didn't have access to get the
  202.         file information). If I had only make changes (I would see
  203.         the parent folder as a "drop box"), I could still open the
  204.         file as long as that fork is empty (this allows me to write
  205.         to an empty file, but not to a fork somebody else has written
  206.         into; this makes putting a file into a "drop box" a one-way
  207.         operation). */
  208.     myOpenRec.pCount = 3;                   /* include requestAccess! */
  209.     myOpenRec.pathname = &path;
  210.     myOpenRec.requestAccess = readEnable+writeEnable;   /* request read/write */
  211.     OpenGS(&myOpenRec);                     /* do the Open call */
  212.  
  213.     
  214.     /*  If I was able to open the file, I know I have full access
  215.         to it, so I will write to it.  If there was an error, put
  216.         up a dialog box informing the user. */
  217.     if (_toolErr) {
  218.         AlertWindow(refIsResource * 2, NULL, 2L);
  219.     } else {
  220.  
  221.         /*  Write the data out.  If there is an error, put up
  222.             a dialog to inform the user. */
  223.         myWriteRec.pCount = 4;
  224.         myWriteRec.refNum = myOpenRec.refNum;
  225.         myWriteRec.dataBuffer = asciiTime;
  226.         myWriteRec.requestCount = 20;
  227.         WriteGS(&myWriteRec);
  228.         if (_toolErr) {
  229.             AlertWindow(refIsResource * 2, NULL, 2L);
  230.         }
  231.         
  232.         /* close the file */
  233.         myCloseRec.pCount = 1;
  234.         myCloseRec.refNum = myOpenRec.refNum;
  235.         CloseGS(&myCloseRec);
  236.     }
  237. }
  238.